<?php
/**
 * GeryEngine
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this release in the file LICENSE
 *
 * @copyright  Copyright (c) 2007 Arjen Brouwer
 * @license    New BSD License
 * @author     Arjen Brouwer
 */

class GeryType {
	
	private $rs;
	private $lineNumber;
	
	protected function error($message) {
		$this->rs->error($message, $this->lineNumber);
	}
	
	protected function expectParameters($method, $format, &$parameters, $quiet = false) 
	{
		$isOptional = false;
		$param = 0;
		
		$funcMap = array(
			'i' => 'is_int'
			,'s' => 'is_string'
			,'f' => 'is_float'
			,'a' => 'is_array'
			,'o' => 'is_object'
			,'b' => 'is_bool'
		);
		
		$nameMap = array(
			'i' => 'integer'
			,'s' => 'string'
			,'f' => 'float'
			,'a' => 'array'
			,'o' => 'object'
			,'m' => 'mixed'
			,'b' => 'boolean'
		);
		
		$minArguments = strpos($format, '|');
		
		if ($minArguments === false)
			$minArguments = strlen($format);
		
		if (count($parameters) < $minArguments) {
			if (! $quiet)
				$this->error("Method $method expects at least $minArguments argument(s)");
				
			return false;
		}
			
		for ($i = 0; $i < strlen($format); $i++) {
			// get the character
			$c = $format[$i];
			
			if ($c == '|') {
				$isOptional = true;
				continue;
			} else {
				// check if a valid format character is given
				if ($c == 'm') {
					continue;
				}
				else if (! key_exists($c, $funcMap)) 
				{
					if (! $quiet)
						$this->error("Invalid parameter format '$c' for method $method");
						
					return false;
				}
					
				// there are too less arguments
				if (! $isOptional && ! key_exists($param, $parameters)) {
					$parameters[$param] = null;
				}
				
				// there are no more parameters and the rest is optional
				if ($isOptional && ! key_exists($param, $parameters))
					return true;
			
			
				// check if the parameter is valid
				if (! call_user_func($funcMap[$c], $parameters[$param])) {
					$name = $nameMap[$c];
					
					// cast the object
					settype($parameters[$param], $name);
					
					// output a warning
					if (! $quiet)
						$this->error(
							sprintf("Argument %d should be of type '%s'", $param + 1, $name));
				}
				
				$param++;
			}
		}
		
		return true;
	}
}
?>